import json
import os
import shutil
import sys
import time
from datetime import datetime, timedelta

from DrissionPage import ChromiumPage, ChromiumOptions
import logging

from PyQt5.QtCore import QTime, QThread, pyqtSignal, QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox

import ui
from common import QTextBrowserStream

# 设置 Chromium 的选项
options = ChromiumOptions()
options.headless = False  # 设置为 False，以便查看浏览器界面

logging.basicConfig(
    level=logging.INFO,
    format='%(levelname)s %(asctime)s %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    filename='logging.txt',
    filemode='a'
)
logger = logging.getLogger(__name__)


def publish_video(page: ChromiumPage, path: str, tags: list) -> None:
    """
    传入ChromiumPage对象，默认是主页, path本地视频地址
    :param tags:
    :param page:
    :param path:
    :return:
    """
    try:
        c_url = page.url
        work_buttons = page.ele('#create-icon', timeout=10000)
        work_buttons.click()
        upload_buttons = page.ele('#text-item-0', timeout=10000)

        upload_buttons.click()
        choose_buttons = page.ele('#select-files-button')
        choose_buttons.click.to_upload(path)

        while True:

            ele = page.ele("tag:ytcp-video-upload-progress")
            if ele:
                t = ele.text
                if "Video upload complete" in t or "上传完毕" in t:
                    break
            time.sleep(1)
        while True:

            title_input = page.ele('#textbox')
            time.sleep(1)
            title = title_input.text
            page.run_js('document.querySelector("#textbox[contenteditable=\'true\']").innerHTML = ""')
            time.sleep(5)

            if title_input:
                content = ""
                for tag in tags:
                    tag = tag.replace("\n", "")
                    content += f" #{tag.strip()} "

                input_s = title + content
                print(title)
                print(content)
                page.run_js('document.querySelector("#textbox[contenteditable=\'true\']").innerHTML = ""')
                title_input.input(input_s)
                break



        for i in range(2):
            continue_buttons = page.ele('#next-button')
            continue_buttons.click()

        continue_buttons = page.ele('#next-button')
        continue_buttons.click()

        common_buttons = page.eles('tag:tp-yt-paper-radio-button')
        for button in common_buttons:
            if button.attr("name") == 'PUBLIC':
                button.click()

        publish_button = page.ele('#done-button')
        publish_button.click()

        time.sleep(10)

        page.refresh()
        time.sleep(5)
        page.get(c_url)
        with open("config.json", "r", encoding="utf-8") as f:
            config = json.load(f)
            sleep_time = config["sleep_time"]
            time.sleep(sleep_time)

    except Exception as e:
        print(e)


def get_account_list(page: ChromiumPage) -> list:
    try:
        account_list = []
        remove_list = []
        avatar_btn = page.ele('#img', timeout=10)
        avatar_btn.click()

        switch_account = page.ele('#items', timeout=10).eles("tag:ytd-compact-link-renderer")[2]
        switch_account.click()

        accounts_ele = page.eles('tag:ytd-account-item-renderer', timeout=10)
        page.ele("#submenu").scroll.to_bottom()
        print("\n\n" + "=" * 30 + "已删除频道" + "=" * 30 + "\n\n")
        for ele in accounts_ele:
            content = ele.ele("tag:tp-yt-paper-item-body").eles("tag:yt-formatted-string")[2].text
            author = ele.ele("tag:tp-yt-paper-item-body").eles("tag:yt-formatted-string")[0].text
            if "频道已移除" in content:
                remove_list.append(author)
                print(f"{author}\n")
            else:
                account_list.append(author)

        with open("已删除频道.txt", "w", encoding="utf-8") as f:
            content = "\n".join(remove_list)
            f.write(content)

        return account_list
    except Exception as e:
        print(e)


def get_no_video_list(path: str) -> list:
    account_list = [p for p in os.listdir(path) if os.path.isdir(os.path.join(path, p)) and not p.startswith('.')]
    no_video_list = []
    print("\n\n" + "=" * 30 + "无视频停止发布频道" + "=" * 30 + "\n\n")
    for account in account_list:
        videos = [v for v in os.listdir(os.path.join(path, account)) if v.endswith(".mp4")]
        if len(videos) == 0:
            no_video_list.append(account)
            print(account)
    with open("无视频停止发布频道.txt", "w", encoding="utf-8") as f:
        content = "\n".join(no_video_list)
        f.write(content)
    return no_video_list


def switch_auth(page: ChromiumPage, published_accounts: list, index=0) -> str:
    try:
        avatar_btn = page.ele('#img', timeout=10)
        avatar_btn.click()
        switch_account = page.ele('#items', timeout=10).eles("tag:ytd-compact-link-renderer")[2]
        switch_account.click()
        time.sleep(6)
        accounts_ele = page.eles('tag:ytd-account-item-renderer', timeout=10)
        page.ele("#submenu").scroll.to_bottom()
        result = "None"
        for ele in accounts_ele:
            content = ele.ele("tag:tp-yt-paper-item-body", timeout=10).eles("tag:yt-formatted-string", timeout=10)[
                2].text
            author = ele.ele("tag:tp-yt-paper-item-body", timeout=10).eles("tag:yt-formatted-string", timeout=10)[
                0].text
            if "频道已移除" in content:
                logger.info("跳过频道已移除:{}".format(author))
                print("跳过频道已移除:{}".format(author))
                continue
            if author not in published_accounts:
                ele.click()
                logger.info("已切换到:{}频道".format(author))
                print("已切换到:{}频道".format(author))
                result = author
                break


    except Exception as e:
        index = index + 1
        result = switch_auth(page, published_accounts, index)
    return result


class Thread(QThread):
    finished = pyqtSignal(object)
    signal = pyqtSignal(object)

    def __init__(self, path, parent=None):
        super().__init__()
        self._stop = False
        self.page = None

        self.path = path
        self.parent = parent
        self.status = False
        self.timer = None
        self.published_accounts = []
        os.makedirs("logs", exist_ok=True)
        log_name = datetime.now().strftime("%Y_%m_%d")
        log_path = os.path.join("logs", log_name + ".txt")
        if os.path.exists(log_path):
            with open(log_path, "r", encoding="utf-8") as f:
                self.published_accounts = f.read().split("\n")

    def execute_task(self, page):
        while True:
            try:
                no_video_list = get_no_video_list(self.path)
                print("开始切换账号")
                published_accounts = list(set(self.published_accounts + no_video_list))
                current_account = switch_auth(page, published_accounts)
                print(f"当前频道: {current_account}")
                if current_account == "None":
                    break

                log_name = datetime.now().strftime("%Y_%m_%d")
                log_path = os.path.join("logs", log_name + ".txt")
                with open(log_path, "w", encoding="utf-8") as f:
                    content = "\n".join(self.published_accounts)
                    f.writelines(content)
                self.published_accounts.append(current_account)
                if len(current_account) > 0:
                    if os.path.exists(os.path.join(self.path, current_account)):
                        print("频道文件夹存在")
                        videos = [os.path.join(self.path, current_account, v) for v in
                                  os.listdir(os.path.join(self.path, current_account)) if v.endswith(".mp4")]
                        print(len(videos), videos)
                        if len(videos) > 0:
                            print("该频道有视频可以发布")
                            if os.path.exists(os.path.join(self.path, current_account, "tags.txt")):
                                with open(os.path.join(self.path, current_account, "tags.txt"), "r",
                                          encoding="utf-8") as f:
                                    tags = f.readlines()
                            else:
                                tags = []

                            path = videos[0]
                            print(f"频道{current_account: >10} 发布视频:{path}")
                            publish_video(page, path, tags)
                            basename = os.path.basename(path)
                            os.makedirs(os.path.join("已发布", current_account), exist_ok=True)
                            shutil.move(path, os.path.join("已发布", current_account, basename))

                        else:
                            print(f"{current_account}频道无视频可以发布")
                    else:
                        print(f"{os.path.join(self.path, current_account)}不存在")
                        self.published_accounts.append(current_account)
                else:
                    break
            except Exception as e:
                print(e)

    def run(self):
        self.page = ChromiumPage(options)
        self.page.get('https://www.youtube.com')
        self.page.ele("#page-title-container", timeout=10000).ele("tag:h1")
        account_list = get_account_list(self.page)
        print("\n\n" + "=" * 30 + "正常频道" + "=" * 30 + "\n\n")
        for account in account_list:
            print(f"{account}\n")
        try:
            while True:
                if self.get_status():
                    break
                current_time = QTime.currentTime()  # 获取当前时间
                with open("config.json", "r", encoding="utf-8") as f:
                    config = json.load(f)
                    set_times = config.get("set_times", [])  # 读取 "set_times" 列表
                    set_times = [time.strip() for time in set_times if time.strip()]  # 去除空格和空元素
                for set_time in set_times:
                    if ":" in set_time:
                        if current_time.hour() == int(set_time.split(":")[0]) and current_time.minute() == int(
                                set_time.split(":")[1]) and not self.status:
                            print("时间到了，执行定时任务")
                            page = self.page
                            self.status = True
                            self.execute_task(page)
                            self.status = False
                            self.published_accounts = []
                import time
                time.sleep(1)
        except Exception as e:
            print(f"错误{e}")
            self.finished.emit(f"错误{e}")
        self.finished.emit("结束")

    def stop(self):
        self._stop = True

    def get_status(self) -> bool:
        return self._stop


class MainWindow(QMainWindow, ui.Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.thread = None
        self.setupUi(self)

        self.text_stream = QTextBrowserStream(self.textBrowser)
        sys.stdout = self.text_stream
        sys.stderr = self.text_stream

        self.sent_account = []

        # self.page = ChromiumPage(options)
        self.pushButton.clicked.connect(self.select_folder)
        self.pushButton_2.clicked.connect(self.start)

        self.pushButton_2.setDisabled(False)
        self.pushButton_3.setDisabled(True)

    def start(self):
        try:

            path = self.lineEdit.text()
            if os.path.exists(path):
                self.get_count()
                get_no_video_list(path)
                self.thread = Thread(path)
                self.thread.finished.connect(self.finished)
                self.thread.signal.connect(self.signal)
                self.pushButton_2.setDisabled(True)
                self.pushButton_3.setDisabled(False)
                self.thread.start()
        except Exception as e:
            print(e)
            QMessageBox.warning(self, "错误", str(e))

    def signal(self, ob):
        self.textBrowser.append(str(ob))

    def stop_thread(self):
        if self.thread is not None:
            self.thread.stop()

    def finished(self, ob):
        self.pushButton_2.setDisabled(False)
        self.pushButton_3.setDisabled(True)
        self.textBrowser.append(str(ob))
        QMessageBox.warning(self, "提示", str(ob))

    def select_folder(self):
        folder_path = QFileDialog.getExistingDirectory(self, "选择文件夹")
        if folder_path:
            self.lineEdit.setText(f'{folder_path}')
            logger.info(f"选择文件夹路径:{folder_path}")
            print(f"选择文件夹路径:{folder_path}")

    def get_count(self):
        # 读取发布的时间点列表
        with open("config.json", "r", encoding="utf-8") as f:
            config = json.load(f)
            set_times = config.get("set_times", [])  # 读取 "set_times" 列表
            set_times = [time.strip() for time in set_times if time.strip()]  # 去除空格和空元素

        lines = []
        today = datetime.now().date()  # 当前日期

        for p in [p for p in os.listdir(self.lineEdit.text()) if not p.startswith('.')]:
            # 获取文件夹中的所有 mp4 文件
            vp = [v for v in os.listdir(os.path.join(self.lineEdit.text(), p)) if v.endswith('.mp4')]
            day = len(vp)  # 统计视频的数量

            if day > 0:
                # 确定当天可以发布的时间点
                publish_date = today
                publish_time_str = set_times[(day - 1) % len(set_times)]  # 根据视频数量获取时间
                publish_time = datetime.strptime(publish_time_str, "%H:%M").time()  # 转换为时间对象

                # 如果该时间已经过去，则将发布日期设置为下一天
                current_time = datetime.now().time()
                if publish_time < current_time:
                    publish_date += timedelta(days=1)

                # 合并日期和时间生成完整的发布时间
                publish_datetime = datetime.combine(publish_date, publish_time)
            else:
                publish_datetime = "无视频可发布"

            # 格式化输出
            if isinstance(publish_datetime, datetime):
                publish_datetime_str = publish_datetime.strftime("%Y-%m-%d %H:%M")
                lines.append(f"{p: <30} , 最后发布时间: {publish_datetime_str}\n")
                print(f"{p: <30} , 最后发布时间: {publish_datetime_str}\n")
            else:
                lines.append(f"{p: <30} , 最后发布时间: {publish_datetime}\n")
                print(f"{p: <30} , 最后发布时间: {publish_datetime}\n")

        # 将统计结果写入文件
        with open("最后发布时间.txt", "w", encoding="utf-8") as f:
            f.writelines(lines)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
